/*
	pattern.h	Pattern database
	Copyright (c) 2001, 2002, 2003, 2004 Kriang Lerdsuwanakij
	email:		lerdsuwa@users.sourceforge.net

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef PATTERN_H
#define PATTERN_H

#include "board.h"
#include "proginfo.h"

typedef signed char pattern_info;

struct raw_pattern_info {
	long	black_win;
	long	white_win;
};

const int max_num_pattern = 8;
const int num_move_index = 15;

struct pattern_data_t {
	int	piece;
	bool	symmetry;
	int	num_pattern;
	const char	*pattern_file;
	const char	*data_file;
	const char	*pattern[max_num_pattern];
};

enum pattern_t {
	PATTERN_ROW1,
	PATTERN_ROW2,
	PATTERN_ROW3,
	PATTERN_ROW4,
	PATTERN_DIAG1,
	PATTERN_DIAG2,
	PATTERN_DIAG3,
	PATTERN_DIAG4,
	PATTERN_DIAG5,
	PATTERN_EDGE_X,
	PATTERN_CORNER5X2,
	PATTERN_UNKNOWN		// Must be the last item
};

extern const pattern_data_t pattern_data[PATTERN_UNKNOWN];

// Power of 3
const int pow_3[] = {
	1,
	3,
	3*3,
	3*3*3,
	3*3*3*3,
	3*3*3*3*3,
	3*3*3*3*3*3,
	3*3*3*3*3*3*3,
	3*3*3*3*3*3*3*3,
	3*3*3*3*3*3*3*3*3,
	3*3*3*3*3*3*3*3*3*3,
	3*3*3*3*3*3*3*3*3*3*3,
	3*3*3*3*3*3*3*3*3*3*3*3,
	3*3*3*3*3*3*3*3*3*3*3*3*3
};

extern pattern_info	*pattern_table[PATTERN_UNKNOWN][num_move_index];

// Map EMPTY, BLACK, WHITE constants to indices for pattern lookup
inline int to_pattern_index(int color)
{
	return color+1;
}

inline int to_board_index(int color)
{
	return color-1;
}

inline int extract_index(int index, int i)
{
	return (index / pow_3[i]) % 3;
}

inline int extract_color(int index, int i)
{
	return to_board_index((index / pow_3[i]) % 3);
}

inline int	get_pattern_piece(pattern_t p)
{
	return pattern_data[p].piece;
}

inline int	get_num_pattern(pattern_t p)
{
	return pattern_data[p].num_pattern;
}

inline int	get_pattern_size(pattern_t p)
{
	return pow_3[get_pattern_piece(p)];
}

inline bool	get_pattern_symmetry(pattern_t p)
{
	return pattern_data[p].symmetry;
}

const char *get_pattern_file(pattern_t p);
const char *get_pattern_data_file(pattern_t p);

void	pattern_table_init();
int	pattern_eval(byte_board_info *board);
int	pattern_eval(byte_board_info *board, pattern_t p, int index);
void	pattern_eval_debug(byte_board_info *board);
void	show_pattern(pattern_t p, int i);
int	to_move_index(int pos);

#endif /* PATTERN_H */
